/**
 * 供应商管理控制器
 * 
 * 该文件负责处理与供应商相关的所有业务逻辑，包括：
 * - 获取供应商列表（支持分页和模糊查询）
 * - 根据ID获取单个供应商信息
 * - 创建新供应商
 * - 更新供应商信息
 * - 删除供应商
 * 
 * 所有接口均通过 Express 路由调用，并遵循项目统一的错误处理和响应格式规范。
 */
const { suppliers: Supplier } = require('../models/init-models')(require('../db').sequelize, require('sequelize').DataTypes); // 导入供应商模型
const { formatPagination, buildLikeQuery, generatePaginationInfo } = require('../utils'); // 导入工具函数

// 引入xlsx库用于处理Excel文件
const XLSX = require('xlsx');

// 引入文件系统模块
const fs = require('fs');

/**
 * 获取供应商列表
 * 支持分页和模糊查询
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @returns {Promise<void>} 返回JSON格式的响应数据
 * 
 * @description
 * 该接口用于获取系统中所有的供应商信息，支持分页和模糊查询。
 * 可以通过 query 参数指定 page、limit 和搜索条件。
 * 使用 Sequelize 的 findAndCountAll 方法同时获取数据和总条数。
 */
const getSupplierList = async (req, res) => {
    try {
        // 格式化分页参数
        const { page, limit, offset } = formatPagination(req.query);
        
        // 定义可搜索的字段
        const searchableFields = ['supplier_name', 'contact_person', 'phone'];
        
        // 构建模糊查询条件
        const whereConditions = buildLikeQuery(req.query, searchableFields);

        // 构建查询选项
        const queryOptions = {
            limit,    // 每页条数
            offset,   // 偏移量
            order: [['created_at', 'DESC']] // 按创建时间倒序排列
        };

        // 如果有查询条件，则添加到查询选项中
        if (Object.keys(whereConditions).length > 0) {
            queryOptions.where = whereConditions;
        }

        // 使用 findAndCountAll 同时获取数据和总条数
        const result = await Supplier.findAndCountAll(queryOptions);

        // 生成分页信息
        const pagination = generatePaginationInfo(result.count, page, limit);

        // 使用统一的分页响应格式返回结果
        res.paginated(result.rows, pagination, '获取供应商列表成功');
    } catch (err) {
        console.error('获取供应商列表失败:', err);
        res.error('获取供应商列表失败');
    }
};

/**
 * 通过ID获取单个供应商信息
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @returns {Promise<void>} 返回JSON格式的响应数据
 * 
 * @description
 * 该接口用于根据传入的ID获取单个供应商的详细信息
 * 使用 Sequelize 的 findByPk 方法进行数据库查询
 * 如果未找到对应记录，返回404状态码。
 */
const getSupplierById = async (req, res) => {
    try {
        // 从请求参数中获取供应商ID
        const supplierId = req.params.id;
        
        // 根据ID查找供应商
        const supplier = await Supplier.findByPk(supplierId);

        // 如果供应商不存在，返回404错误
        if (!supplier) {
            return res.error('供应商不存在', 1, 404);
        }

        // 返回供应商信息
        res.success(supplier, '获取供应商信息成功');
    } catch (err) {
        console.error('获取供应商信息失败:', err);
        res.error('获取供应商信息失败');
    }
};

/**
 * 添加新供应商
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @returns {Promise<void>} 返回JSON格式的响应数据
 * 
 * @description
 * 该接口用于创建新的供应商记录
 * 使用 Sequelize 的 create 方法将数据写入数据库。
 */
const addSupplier = async (req, res) => {
    try {
        // 检查供应商名称是否已存在
        const existingSupplier = await Supplier.findOne({
            where: {
                supplier_name: req.body.supplier_name
            }
        });
        
        if (existingSupplier) {
            return res.error('供应商名称已存在');
        }
        
        // 创建新供应商
        const supplier = await Supplier.create(req.body);
        
        // 返回成功响应
        res.success(supplier, '添加供应商成功');
    } catch (err) {
        console.error('添加供应商失败:', err);
        res.error('添加供应商失败');
    }
};

/**
 * 更新供应商信息
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @returns {Promise<void>} 返回JSON格式的响应数据
 * 
 * @description
 * 该接口用于更新现有供应商信息
 * 首先通过ID查找要更新的记录，如果不存在则返回404。
 * 然后使用 Sequelize 的 update 方法更新数据库记录。
 */
const updateSupplier = async (req, res) => {
    try {
        // 从请求参数中获取供应商ID
        const supplierId = req.params.id;
        
        // 先查找供应商是否存在
        const existingSupplier = await Supplier.findByPk(supplierId);
        if (!existingSupplier) {
            // 如果供应商不存在，返回404错误
            return res.error('供应商不存在', 1, 404);
        }

        // 检查要更新的供应商名称是否与其他供应商重复（排除自己）
        if (req.body.supplier_name) {
            const duplicateSupplier = await Supplier.findOne({
                where: {
                    supplier_name: req.body.supplier_name,
                    supplier_id: {
                        [require('sequelize').Op.ne]: supplierId
                    }
                }
            });
            
            if (duplicateSupplier) {
                return res.error('供应商名称已存在');
            }
        }

        // 更新供应商信息
        const [updatedCount] = await Supplier.update(req.body, {
            where: {
                supplier_id: supplierId
            }
        });

        // 重新获取更新后的供应商信息
        const updatedSupplier = await Supplier.findByPk(supplierId);

        // 返回成功响应
        res.success(updatedSupplier, '更新供应商成功');
    } catch (err) {
        console.error('更新供应商失败:', err);
        res.error('更新供应商失败');
    }
};

/**
 * 删除供应商
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @returns {Promise<void>} 返回JSON格式的响应数据
 * 
 * @description
 * 该接口用于删除指定的供应商记录。
 * 删除操作使用 Sequelize 的 destroy 方法执行。
 * 如果没有删除任何记录，说明供应商不存在。
 */
const delSupplier = async (req, res) => {
    try {
        // 从请求参数中获取供应商ID
        const supplierId = req.params.id;
        
        // 删除供应商
        const deletedCount = await Supplier.destroy({
            where: {
                supplier_id: supplierId
            }
        });
        
        // 如果没有删除任何记录，说明供应商不存在
        if (deletedCount === 0) {
            return res.error('供应商不存在', 1, 404);
        }
        
        // 返回成功响应
        res.success({ deletedCount }, '删除供应商成功');
    } catch (err) {
        console.error('删除供应商失败:', err);
        res.error('删除供应商失败');
    }
};

/**
 * 从Excel文件导入供应商数据
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @returns {Promise<void>} 返回JSON格式的响应数据
 * 
 * @description
 * 该接口用于从Excel文件导入供应商数据。
 * 解析Excel文件，将数据转换为供应商对象，然后批量创建供应商。
 */
const importSuppliers = async (req, res) => {
    try {
        // 检查是否有上传文件
        if (!req.file) {
            return res.error('请上传Excel文件', 1, 400);
        }

        // 读取上传的Excel文件
        const workbook = XLSX.readFile(req.file.path);
        
        // 获取第一个工作表
        const sheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[sheetName];
        
        // 将工作表转换为JSON数据
        const jsonData = XLSX.utils.sheet_to_json(worksheet);
        
        // 检查是否有数据
        if (!jsonData || jsonData.length === 0) {
            // 删除上传的文件
            fs.unlinkSync(req.file.path);
            return res.error('Excel文件中没有数据', 1, 400);
        }

        // 转换数据格式并验证必填字段
        const suppliersData = jsonData.map((row, index) => {
            // 检查必填字段
            if (!row['供应商名称']) {
                throw new Error(`第${index + 2}行供应商名称不能为空`);
            }
            
            if (!row['联系电话']) {
                throw new Error(`第${index + 2}行联系电话不能为空`);
            }
            
            if (!row['联系人']) {
                throw new Error(`第${index + 2}行联系人不能为空`);
            }
            
            // 转换数据格式
            return {
                supplier_name: row['供应商名称'],
                phone: row['联系电话'],
                contact_person: row['联系人'],
                address: row['供应商地址'] || ''
            };
        });

        // 检查是否有重复的供应商名称
        const supplierNames = suppliersData.map(supplier => supplier.supplier_name);
        const duplicateNames = supplierNames.filter((name, index) => supplierNames.indexOf(name) !== index);
        
        if (duplicateNames.length > 0) {
            throw new Error(`Excel文件中存在重复的供应商名称: ${[...new Set(duplicateNames)].join(', ')}`);
        }

        // 检查数据库中是否已存在同名供应商
        for (const supplierData of suppliersData) {
            const existingSupplier = await Supplier.findOne({
                where: {
                    supplier_name: supplierData.supplier_name
                }
            });
            
            if (existingSupplier) {
                throw new Error(`供应商 "${supplierData.supplier_name}" 已存在`);
            }
        }

        // 批量创建供应商
        const createdSuppliers = await Supplier.bulkCreate(suppliersData, {
            validate: true, // 启用验证
            returning: true // 返回创建的记录
        });

        // 删除上传的文件
        fs.unlinkSync(req.file.path);

        // 返回成功响应
        res.success({
            importedCount: createdSuppliers.length,
            suppliers: createdSuppliers
        }, `成功导入${createdSuppliers.length}个供应商`);
    } catch (err) {
        console.error('导入供应商失败:', err);
        
        // 删除上传的文件（如果存在）
        if (req.file && req.file.path && fs.existsSync(req.file.path)) {
            fs.unlinkSync(req.file.path);
        }
        
        // 根据错误类型返回不同的错误信息
        if (err.name === 'SequelizeUniqueConstraintError') {
            res.error(`数据重复：${err.message}`, 1, 400);
        } else if (err.name === 'SequelizeValidationError') {
            res.error(`数据验证失败: ${err.message}`, 1, 400);
        } else {
            res.error(err.message || '导入供应商失败');
        }
    }
};

/**
 * 批量操作供应商
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @returns {Promise<void>} 返回JSON格式的响应数据
 * 
 * @description
 * 该接口用于批量操作供应商，支持批量删除等操作。
 * 通过 action 参数指定操作类型，data 参数指定操作的数据。
 */
const batchSupplierOperation = async (req, res) => {
    try {
        const { action, data } = req.body;
        
        switch (action) {
            case 'delete':
                // 批量删除供应商
                const deletedCount = await Supplier.destroy({
                    where: {
                        supplier_id: {
                            [require('sequelize').Op.in]: data.ids
                        }
                    }
                });
                
                res.success({ deletedCount }, '批量删除供应商成功');
                break;
                
            default:
                res.error('不支持的操作类型');
        }
    } catch (err) {
        console.error('批量操作供应商失败:', err);
        res.error('批量操作供应商失败');
    }
};

// 导出所有路由处理函数
module.exports = {
    getSupplierById,           // 获取单个供应商信息
    getSupplierList,           // 获取供应商列表
    addSupplier,               // 添加新供应商
    updateSupplier,            // 更新供应商信息
    delSupplier,               // 删除供应商
    importSuppliers,           // 从Excel导入供应商
    batchSupplierOperation     // 批量操作供应商
};